package cate.game.server.cli;

import cate.game.client.msg.GameMsg;
import cate.game.client.msg.MsgConfig;
import cate.game.client.msg.MsgOutput;
import easy.java.codec.JsonCodec;
import easy.java.codec.ZlibCodec;
import easy.socket.util.BBU;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class MsgEncode {

    public static WebSocketFrame encode(MsgOutput msg) {
        MsgConfig conf = msg.conf();
        if(GameMsg.CODEC_TEXT_FRAME == conf.codec) {
            StringBuilder sb = new StringBuilder();
            sb.append(conf.a);
            sb.append("-");
            sb.append(conf.b);
            sb.append(":");
            try {
                sb.append(JsonCodec.instance().encodeString(msg));
            } catch (Exception e) {
                sb.append("err#" + e.getMessage());
                log.error("", e);
            }
            return new TextWebSocketFrame(sb.toString());
        }
        ByteBuf buf = BBU.buffer();
        buf.writeInt(conf.a);
        buf.writeInt(conf.b);
        buf.writeByte(conf.codec);
        switch (conf.codec) {
            case GameMsg.CODEC_JSON:
                handleJson(buf, msg);
                break;
            case GameMsg.CODEC_JSON_ZIP:
                handleJsonZip(buf, msg);
                break;
        }
        return new BinaryWebSocketFrame(buf);
    }

    private static void handleJson(ByteBuf buf, MsgOutput msg) {
        try {
            byte[] bytes = JsonCodec.instance().encodeBytes(msg);
            BBU.writeAutoBytes(buf, bytes);
        } catch (Exception e) {
            log.error("", e);
        }
    }

    private static void handleJsonZip(ByteBuf buf, MsgOutput msg) {
        try {
            byte[] bytes = JsonCodec.instance().encodeBytes(msg);
            bytes = ZlibCodec.instance().compress(bytes);
            BBU.writeAutoBytes(buf, bytes);
        } catch (Exception e) {
            log.error("", e);
        }
    }
}
